import re
import sys

def read_file_safely(file_path):
    """安全读取文件内容，统一错误处理"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return f.read(), None
    except FileNotFoundError:
        return None, f"错误: 文件 '{file_path}' 不存在"
    except Exception as e:
        return None, f"错误: 读取文件时发生异常 - {e}"

# 基础功能：字符、单词、句子统计
def count_chars(file_path):
    """统计字符数（包括空格和换行符）"""
    content, error = read_file_safely(file_path)
    if error:
        return error
    return len(content)

def count_words(file_path):
    """统计单词数，支持含撇号的英文单词"""
    content, error = read_file_safely(file_path)
    if error:
        return error
    # 优化正则：支持含撇号的英文单词，且严格以字母开头和结尾
    words = re.findall(r"\b[a-zA-Z]+(?:[''’][a-zA-Z]+)*\b", content)
    return len(words)

def count_sentences(file_path):
    """统计句子数，避免将缩写误判为句子结束"""
    content, error = read_file_safely(file_path)
    if error:
        return error
    
    # 改进的句子分割：避免将 Mr. Dr. 等缩写误判为句子结束
    # 使用正向否定查找，确保点号前面不是缩写词
    abbreviations = r'\b(Mr|Mrs|Ms|Dr|Prof|Rev|Gen|Capt|Lt|Col|Sr|Jr|St|Ave|Blvd|Rd|etc|i\.e|e\.g)\.'
    
    # 临时替换缩写中的点号
    temp_content = re.sub(abbreviations, r'\1@@@', content)
    
    # 分割句子
    sentences = re.split(r'[.!?]+', temp_content)
    
    # 过滤空句子
    valid_sentences = [s for s in sentences if s.strip()]
    return len(valid_sentences)

# 扩展功能：代码行、空行、注释行统计
def count_code_lines(file_path):
    """统计代码行、空行、注释行"""
    content, error = read_file_safely(file_path)
    if error:
        # 只返回3个值，将错误信息作为第一个返回值
        return error, 0, 0
    
    lines = content.splitlines()
    valid = 0   # 有效代码行
    empty = 0   # 空行
    comment = 0 # 注释行
    
    for line in lines:
        stripped = line.strip()
        
        # 空行检测（完全空白的行）
        if not stripped:
            empty += 1
            continue
        
        # 检测单行注释（以 # 或 // 开头）
        if stripped.startswith(('#', '//')):
            comment += 1
            continue
            
        # 检测单行块注释 /* ... */
        if stripped.startswith('/*') and stripped.endswith('*/'):
            comment += 1
            continue
        
        # 检测行内注释
        has_inline_comment = False
        code_part = stripped
        
        if '//' in stripped:
            parts = stripped.split('//', 1)
            code_part = parts[0].strip()
            has_inline_comment = True
        elif '#' in stripped:
            parts = stripped.split('#', 1)
            code_part = parts[0].strip()
            has_inline_comment = True
        
        # 如果有代码部分，算作有效代码行
        if code_part:
            valid += 1
            # 如果同时有注释，也计数为注释行
            if has_inline_comment:
                comment += 1
        else:
            # 只有注释没有代码
            comment += 1
    
    # 返回3个值，与测试用例期望一致
    return valid, empty, comment

def analyze_file_details(file_path):
    """综合分析文件，返回所有统计信息"""
    content, error = read_file_safely(file_path)
    if error:
        return None, error
    
    # 基础统计
    chars = len(content)
    words = len(re.findall(r"\b[a-zA-Z]+(?:[''’][a-zA-Z]+)*\b", content))
    
    # 句子统计（使用改进的方法）
    abbreviations = r'\b(Mr|Mrs|Ms|Dr|Prof|Rev|Gen|Capt|Lt|Col|Sr|Jr|St|Ave|Blvd|Rd|etc|i\.e|e\.g)\.'
    temp_content = re.sub(abbreviations, r'\1@@@', content)
    sentences = re.split(r'[.!?]+', temp_content)
    sentence_count = len([s for s in sentences if s.strip()])
    
    # 行统计 - 调整为匹配新的返回值格式
    code_stats = count_code_lines(file_path)
    if isinstance(code_stats[0], str):  # 检查是否有错误
        return None, code_stats[0]
    valid_lines, empty_lines, comment_lines = code_stats
    
    result = {
        'chars': chars,
        'words': words,
        'sentences': sentence_count,
        'code_lines': valid_lines,
        'empty_lines': empty_lines,
        'comment_lines': comment_lines,
        'total_lines': valid_lines + empty_lines + comment_lines
    }
    
    return result, None

def print_usage():
    """打印使用说明"""
    print("命令格式：python wc3.py [参数] [文件名]")
    print("基础参数：")
    print("  -c : 统计字符数")
    print("  -w : 统计单词数") 
    print("  -s : 统计句子数")
    print("扩展参数：")
    print("  -l : 统计有效代码行数")
    print("  -e : 统计空行数")
    print("  -com : 统计注释行数")
    print("  -a : 显示所有统计信息")
    print("示例：")
    print("  python wc3.py -c example.txt")
    print("  python wc3.py -a example.py")

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print_usage()
        sys.exit(1)
    
    param = sys.argv[1]
    file_name = sys.argv[2]
    
    if param == '-c':
        result = count_chars(file_name)
        print(f"字符数: {result}")
    elif param == '-w':
        result = count_words(file_name)
        print(f"单词数: {result}")
    elif param == '-s':
        result = count_sentences(file_name)
        print(f"句子数: {result}")
    elif param == '-l':
        # 调整为匹配新的返回值格式
        stats = count_code_lines(file_name)
        if isinstance(stats[0], str):  # 错误信息
            print(stats[0])
        else:
            valid, _, _ = stats
            print(f"有效代码行: {valid}")
    elif param == '-e':
        # 调整为匹配新的返回值格式
        stats = count_code_lines(file_name)
        if isinstance(stats[0], str):  # 错误信息
            print(stats[0])
        else:
            _, empty, _ = stats
            print(f"空行数: {empty}")
    elif param == '-com':
        # 调整为匹配新的返回值格式
        stats = count_code_lines(file_name)
        if isinstance(stats[0], str):  # 错误信息
            print(stats[0])
        else:
            _, _, comment = stats
            print(f"注释行数: {comment}")
    elif param == '-a':
        # 显示所有统计信息
        result, error = analyze_file_details(file_name)
        if error:
            print(error)
        if result:
            print("=" * 40)
            print(f"文件分析报告: {file_name}")
            print("=" * 40)
            print(f"字符数: {result['chars']}")
            print(f"单词数: {result['words']}")
            print(f"句子数: {result['sentences']}")
            print(f"有效代码行: {result['code_lines']}")
            print(f"空行数: {result['empty_lines']}")
            print(f"注释行数: {result['comment_lines']}")
            print(f"总行数: {result['total_lines']}")
            print("=" * 40)
    else:
        print("错误: 不支持的命令参数")
        print_usage()
        sys.exit(1)
